using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;

namespace yyyy.cccc.zzzz.framework
{

class SelectedInfo
{
    public string searchText;
    public object fieldValue;
    public object fieldInfo;
    public object obj;

    public System.Type showType;

    public System.Type GetFieldType()
    {
        var a = fieldInfo as System.Reflection.FieldInfo;
        if(a != null)
        {
            return a.FieldType;
        }

        var b = fieldInfo as System.Reflection.PropertyInfo;
        if(b != null)
        {
            return b.PropertyType;
        }

        return null;
    }

    public System.Type GetValueType()
    {
        if(fieldValue != null)
        {
            return fieldValue.GetType();
        }

        return GetFieldType();
    }

    public string GetFieldName()
    {
        var a = fieldInfo as System.Reflection.FieldInfo;
        if(a != null)
        {
            return a.Name;
        }

        var b = fieldInfo as System.Reflection.PropertyInfo;
        if(b != null)
        {
            return b.Name;
        }

        return null;
    }
}

//show array, Ilist, Idictionary, hashset, hashtable...texture


enum SearchMode
{
    assembly,
    scene,
    resource,
    assetbundle,
}

public class InspectDataView
{
    List<object> selectedObjs = new List<object>();

    Vector2 scrollViewPos;
    string searchTextInternal { get; set; }
    public string searchText { get; set; }

    bool publicMemberOnly = false;

    bool showMethods;
    
    // HashSet<System.Type> baseTypeSet = new HashSet<System.Type>(){typeof(System.Int16), 
    //                                                             typeof(System.Int32), 
    //                                                             typeof(System.Int64), 
    //                                                             typeof(System.UInt16), 
    //                                                             typeof(System.UInt32), 
    //                                                             typeof(System.UInt64),
    //                                                             typeof(System.Byte),
    //                                                             typeof(System.SByte),
    //                                                             typeof(System.Char),
    //                                                             typeof(System.Boolean),
    //                                                             typeof(System.String),
    //                                                             typeof(System.Single),
    //                                                             typeof(System.Double),
    //                                                             typeof(System.UIntPtr),
    //                                                             typeof(System.IntPtr),

    //                                                             };

    // Dictionary<System.Type, System.Func<object, string>> showSimpleValueTypeSet = new Dictionary<System.Type, System.Func<object, string>>{
    //                                                             {typeof(UnityEngine.Vector2), ToString},
    //                                                             {typeof(UnityEngine.Vector3), ToString},
    //                                                             {typeof(UnityEngine.Vector4), ToString},
    //                                                             {typeof(UnityEngine.Vector2Int), ToString},
    //                                                             {typeof(UnityEngine.Vector3Int), ToString},
    //                                                             {typeof(UnityEngine.Quaternion), ToString},
    //                                                             {typeof(UnityEngine.Rect), ToString},
    //                                                             {typeof(UnityEngine.RectInt), ToString},
    //                                                             {typeof(UnityEngine.RectOffset), ToString},
    //                                                             };

    Dictionary<System.Type, System.Func<object, string>> showValueTypeSet = new Dictionary<System.Type, System.Func<object, string>>(){{typeof(System.Exception), ToExceptionMessage},
                                                                                                                                        {typeof(KeyValuePair<,>), KeyValueToString},
                                                                                                                                                
                                                                                                                                        {typeof(System.Type), TypeToString},};

    int pageIndex = 0;
    public int maxPageItemNum = 500;

    public System.Action keyboardBtnCallback;



    // Dictionary<System.Type, System.Func<object, string>> simpleTypeStrFuncMap = new Dictionary<System.Type, System.Func<object, string>>(){{typeof(UnityEngine.Vector3), (object b) =>
    // {
    //     Vector3 a = (Vector3)b;
    //     return string.Format("({0}, {1}, {2})", a.x, a.y, a.z);
    // }
    // }};




    UnityEngine.SceneManagement.Scene dontDestroyOnLoadScene;

    bool inited;
    public bool enableMaxWidth { get; set; }
    public void Init()
    {
        if(inited)
        {
            return;
        }
        inited = false;

        var go = new GameObject("DontDestroyOnLoad Object");
        GameObject.DontDestroyOnLoad(go);
        dontDestroyOnLoadScene = go.scene;
        GameObject.Destroy(go);
    }

    static string KeyValueToString(object b)
    {
        var keyProInfo = b.GetType().GetProperty("Key");
        var valProInfo = b.GetType().GetProperty("Value");
        return keyProInfo.GetValue(b).ToString() + "->" + valProInfo.GetValue(b).ToString();
    }

    static string ToString(object b)
    {
        return b.ToString();
    }

    static string TypeToString(object b)
    {
        if(b != null)
        {
            return b.ToString();
        }

        return "null";
    }

    static string ToExceptionMessage(object b)
    {
        if(b == null)
        {
            return "null";
        }

        return ((System.Exception)b).Message;
    }

    string GetShowTypeName(object a, System.Type showType = null)
    {
        var d = a as SelectedInfo;
        if(d != null)
        {
            if(d.GetFieldType() != null)
            {
                // string b = GetShowTypeName(d.GetFieldType(), out outName);

                // var value = d.fieldValue?.ToString();
                return "->" + d.GetFieldName() + " | " + GetShowTypeName(d.fieldValue, d.GetFieldType());
            }
            else
            {
                
                // if(d.showType == null)
                // {
                //     return null;
                // }
                // else
                {
                    // if(d.fieldValue != null)
                    {
                        // string ret = GetShowTypeName(d.fieldValue, out outName);
                        // outName = GetTypeFullName(d.showType);
                        // return ret;

                        // return "object: " + d.fieldValue.ToString() + " | type:" + GetTypeFullName(d.showType);
                        return GetShowTypeName(d.fieldValue, d.showType);

                        // return "instace(" + GetTypeFullName(d.showType) + ")";
                    }

                    // // outName = GetTypeFullName(d.showType);
                    // // return "type: ";

                    // return "type: " + GetTypeFullName(d.showType);
                }
            }
        }
        else
        {
            // if(a is UnityEngine.SceneManagement.Scene)
            // {
            //     outName = ((UnityEngine.SceneManagement.Scene)a).name;
            //     return "scene";
            // }
            // else

            if(a != null)
            {
                // if(a is System.Type)
                // {
                //     var c = a as System.Type;
                    
                //     string typeType = null;
                //     if(c.IsEnum)
                //     {
                //         typeType = "enum";
                //     }
                //     else
                //     {
                //         if(c.IsValueType)
                //         {
                //             typeType = "valueType";
                //         }
                //         else if(c.IsClass)
                //         {
                //             typeType = "class";
                //         }
                //         else if(c.IsInterface)
                //         {
                //             typeType = "interface";
                //         }
                //         else if(c.IsArray)
                //         {
                //             typeType = "array";
                //         }
                //         else if(c.IsSubclassOf(typeof(System.Delegate)))
                //         {
                //             typeType = "delegate";
                //         }
                //         else
                //         {
                //             typeType = "unknown type";
                //         }
                //     }

                //     return "type: " + typeType + ": " + GetTypeFullName(c) + " | type:" + GetTypeFullName(showType??a.GetType());;
                // }
                // else
                {
                    string objTypeName = "object";
                    if(a is UnityEngine.Object)
                    {
                        var uniObj = a as UnityEngine.Object;
                        string unityObjName = "";
                        unityObjName = uniObj.name;
                        string unityTypeName = "unity_object";
                        if(a is UnityEngine.Component)
                        {
                            unityTypeName = "unity_component";
                        }
                        else if(a is UnityEngine.GameObject)
                        {
                            unityTypeName = "unity_gameobj";
                        }

                        objTypeName = unityTypeName + "(" + unityObjName + "," + uniObj.GetInstanceID() + ")";
                    }
                    else if(a is UnityEngine.SceneManagement.Scene)
                    {
                        string unityObjName = "";
                        unityObjName = ((UnityEngine.SceneManagement.Scene)a).name;
                        objTypeName = "unity_scene(" + unityObjName + ")";
                    }
                    else if(a is System.Type)
                    {
                        objTypeName = "type_object";
                    }

                    return objTypeName + ":" + a.ToString() + " | type:" + GetTypeFullName(showType??a.GetType());

                    // string objName = null;
                    // if(a is UnityEngine.Object)
                    // {
                    //     var gameobj = a as UnityEngine.Object;
                    //     objName = gameobj.name;
                    // }
                    // else if(a is UnityEngine.SceneManagement.Scene)
                    // {
                    //     var s = (UnityEngine.SceneManagement.Scene)a;
                    //     objName = s.name;
                    // }

                    // // if()
                    // // {
                    // //     outName = gameobj.name;
                    // //     return "unity_object()";
                    // // }
                    // // else
                    // {
                    //     outName = GetTypeFullName(a.GetType());
                    //     string temp = null;
                    //     return ((objName != null? objName: "") + " | object") + "(" + GetShowTypeName(a.GetType(), out temp) + ")";
                    // }
                }
            }
            else
            {
                if(showType == null)
                {
                    return "null";
                }

                var c = showType;
                    
                string typeType = null;
                if(c.IsEnum)
                {
                    typeType = "enum";
                }
                else
                {
                    if(c.IsValueType)
                    {
                        typeType = "valueType";
                    }
                    else if(c.IsClass)
                    {
                        typeType = "class";
                    }
                    else if(c.IsInterface)
                    {
                        typeType = "interface";
                    }
                    else if(c.IsArray)
                    {
                        typeType = "array";
                    }
                    else if(c.IsSubclassOf(typeof(System.Delegate)))
                    {
                        typeType = "delegate";
                    }
                    else
                    {
                        typeType = "unknown type";
                    }
                }

                return typeType + ": " + GetTypeFullName(c);
            }
        }
    }

    public void ShowGUI()
    {   
        var oldButtonTextAlignment = GUI.skin.button.alignment;
        GUI.skin.button.alignment = TextAnchor.MiddleLeft;
        
        try
        {
            Show();
        }
        catch(System.Exception e)
        {
            Debug.LogException(e);
        }

        GUI.skin.button.alignment = oldButtonTextAlignment;
    }


    // bool layoutChanged = false;

    

    void Show()
    {
        if(Event.current.type == EventType.Layout)
        {
            if(searchText != searchTextInternal)
            {
                searchTextInternal = searchText;
                pageIndex = 0;

                // layoutChanged = true;
            }
        }

        // if(layoutChanged && Event.current.type == EventType.Repaint)
        // {
        //     layoutChanged = false;
        //     return;
        // }

        GUILayout.BeginVertical(enableMaxWidth? GUILayout.MaxWidth(Screen.width): GUILayout.ExpandWidth(true));
        // GUILayout.BeginVertical();


        GUILayout.BeginHorizontal();
        
        
        // if(keyboardBtnCallback != null)
        // {
        //     if(GUILayout.Button("search:", GUILayout.ExpandWidth(false)))
        //     {
        //         keyboardBtnCallback();   
        //     }
        // }
        // else
        {
            GUILayout.Label("search:", GUILayout.ExpandWidth(false));
        }
        
        if(keyboardBtnCallback != null)
        {
            if(GUILayout.Button(string.IsNullOrEmpty(searchTextInternal)?"click here to input": searchTextInternal, GUILayout.MinWidth(Screen.width * 0.3f)))
            {
                keyboardBtnCallback();
            }
        }
        else
        {
            searchText = GUILayout.TextField(searchTextInternal, GUILayout.MinWidth(Screen.width * 0.3f));

            // newSearchText = GUILayout.TextField(searchText);
            
            // if(newSearchText != searchText)
            // {
            //     searchText = newSearchText;
            //     pageIndex = 0;

            //     // layoutChanged = true;
            // }
        }
        


        // publicMemberOnly = GUILayout.Toggle(publicMemberOnly, "only public member", GUILayout.ExpandWidth(false));
        GUILayout.EndHorizontal();

        


        scrollViewPos = GUILayout.BeginScrollView(scrollViewPos);
        GUILayout.BeginVertical();

        // if(selectedObjs.Count > 0)
        {
            Title("selected objects(" + selectedObjs.Count + "):");
        }

        for(int i = 0; i < selectedObjs.Count; i++)
        {
            var a = GetSelectedObj(i);
            
            FontStyle oldFontStyle = GUI.skin.button.fontStyle;
            if(i == selectedObjs.Count - 1)
            {
                GUI.skin.button.fontStyle = FontStyle.Bold;
            }

            try
            {
                string btnText = null;
                if (i == 0)
                {
                    btnText = "search mode: " + a.fieldValue;
                }
                else
                {

                    SearchMode searchMode = (SearchMode)GetSelectedObj(0).fieldValue;
                    if (i == 1 && searchMode == SearchMode.assembly)
                    {
                        {
                            var b = a.fieldValue as System.Reflection.Assembly;
                            btnText = "assembly: " + b.GetName().Name;

                        }
                    }
                    else
                    {
                        string typeName = GetShowTypeName(a);
                        btnText = typeName;

                     
                    }
                }


                if (GUILayout.Button(btnText))
                {
                    if (i == selectedObjs.Count - 1)
                    {
                        searchText = (selectedObjs[i] as SelectedInfo).searchText;
                        selectedObjs.RemoveRange(i, selectedObjs.Count - i);
                    }
                    else
                    {
                        searchText = (selectedObjs[i + 1] as SelectedInfo).searchText;
                        selectedObjs.RemoveRange(i + 1, selectedObjs.Count - i - 1);
                    }

                    // newSearchText = null;
                    pageIndex = 0;
                    break;
                }
            }
            catch (System.Exception e)
            {
                throw e;
            }
            finally
            {
                GUI.skin.button.fontStyle = oldFontStyle;
            }
        };

        
        GUILayout.Label("");
        GUILayout.Label("---------data info----------");

        if(selectedObjs.Count <= 0)
        {
            Title("search modes:");
            
            var searchModes = System.Enum.GetNames(typeof(SearchMode));

            for(int i = 0; i < searchModes.Length; i++)
            {
                var mode = System.Enum.Parse(typeof(SearchMode), searchModes[i]);
                if(GUILayout.Button(mode.ToString()))
                {
                    PushSelectedObj(mode);

                    break;
                }
            }
        }
        else if(selectedObjs.Count == 1)
        {
            switch((SearchMode)GetSelectedObj(0).fieldValue)
            {
                case SearchMode.assembly:
                {
                    System.Reflection.Assembly[] assemblies = System.AppDomain.CurrentDomain.GetAssemblies();

                    if(!string.IsNullOrEmpty(searchTextInternal))
                    {
                        assemblies = System.Array.FindAll(assemblies, (a) => a.GetName().Name.ToLower().Contains(searchTextInternal.ToLower()));
                    }
                    
                    Title(string.Format("assemblies({0}):", assemblies.Length));
                    for(int i = 0; i < assemblies.Length; i++)
                    {
                        var assembly = assemblies[i];
                        if(GUILayout.Button(assembly.GetName().Name))
                        {
                            PushSelectedObj(assembly);
                            
                            break;
                        }
                    }
                }
                break;
                case SearchMode.scene:
                {
                    Title("scenes:");
                    List<UnityEngine.SceneManagement.Scene> scenes = new List<UnityEngine.SceneManagement.Scene>();
                    for(int i = 0; i < UnityEngine.SceneManagement.SceneManager.sceneCount; i++)
                    {
                        var scene = UnityEngine.SceneManagement.SceneManager.GetSceneAt(i);
                        scenes.Add(scene);
                    }

                    if(dontDestroyOnLoadScene.rootCount > 0)
                    {
                        scenes.Add(dontDestroyOnLoadScene);
                    }

                    if(!string.IsNullOrEmpty(searchTextInternal))
                    {
                        scenes = scenes.FindAll((a) => a.name.ToLower().Contains(searchTextInternal.ToLower()));
                    }

                    scenes.ForEach((scene) =>
                    {
                        if(GUILayout.Button(scene.name))
                        {
                            PushSelectedObj(scene);
                        }
                    });
                }
                break;
                case SearchMode.resource:
                {
                    var  resObjs = Resources.FindObjectsOfTypeAll<UnityEngine.Object>();

                    if(!string.IsNullOrEmpty(searchTextInternal))
                    {
                        resObjs = System.Array.FindAll(resObjs, (a) => a.name.ToLower().Contains(searchTextInternal.ToLower()) || a.GetType().ToString().ToLower().Contains(searchTextInternal.ToLower()) );
                    }


                    int beginItemIndex = pageIndex * maxPageItemNum;
                    int endItemIndex = Mathf.Min((pageIndex + 1) * maxPageItemNum, resObjs.Length);

                    GUILayout.BeginHorizontal();
                    Title(string.Format("resources({0}):", resObjs.Length));
                    if(GUILayout.Button("[" + beginItemIndex + "-" + endItemIndex + "]", GUILayout.ExpandWidth(false)))
                    {
                        int pageNum = (resObjs.Length / maxPageItemNum);
                        if(resObjs.Length % maxPageItemNum != 0)
                        {
                            pageNum++;
                        }

                        pageIndex++;
                        pageIndex %= pageNum;
                    }
                    GUILayout.EndHorizontal();


                    for(int i = pageIndex * maxPageItemNum; i < (pageIndex + 1) * maxPageItemNum && i < resObjs.Length; i++)
                    {
                        var res = resObjs[i];
                        if(GUILayout.Button(res.name + " | " + res.GetType()))
                        {
                            // SelectedInfo info = new SelectedInfo();
                            // info.fieldValue = res;
                            // info.showType = res.GetType();
                            // PushSelectedObj(info);
                            
                            PushSelectedObj(res);

                            break;
                        }
                    }

                    // Title(string.Format("resources({0}):", resObjs.Length));
                    // for(int i = 0; i < resObjs.Length; i++)
                    // {
                    //     var res = resObjs[i];
                    //     if(GUILayout.Button(res.name + " | " + res.GetType()))
                    //     {
                    //         SelectedInfo info = new SelectedInfo();
                    //         info.fieldValue = res;
                    //         info.showType = res.GetType();
                    //         PushSelectedObj(info);
                    //         newSearchText = null;
                    //         break;
                    //     }
                    // }
                }
                break;
                case SearchMode.assetbundle:
                {
                    var allab = AssetBundle.GetAllLoadedAssetBundles();
                    List<AssetBundle> abList = new List<AssetBundle>();
                    foreach(var b in allab)
                    {
                        abList.Add(b);
                    }

                    if(!string.IsNullOrEmpty(searchTextInternal))
                    {
                        abList = abList.FindAll((a) => a.name.ToLower().Contains(searchTextInternal.ToLower()) );
                    }

                    Title(string.Format("assetbundles({0}):", abList.Count));
                    for(int i = 0; i < abList.Count; i++)
                    {
                        var res = abList[i];
                        if(GUILayout.Button(res.name + " | " + res.isStreamedSceneAssetBundle))
                        {
                            // SelectedInfo info = new SelectedInfo();
                            // info.fieldValue = res;
                            // info.showType = res.GetType();
                            // PushSelectedObj(info);

                            PushSelectedObj(res);
                            break;
                        }
                    }
                }
                break;
            }
        }
        else
        {
            if(selectedObjs.Count == 2 && (SearchMode)(GetSelectedObj(0).fieldValue) == SearchMode.assembly)
            {
                var selectedAssembly = GetSelectedObj(selectedObjs.Count - 1).fieldValue as System.Reflection.Assembly;
                if(selectedAssembly != null)
                {
                    System.Type[] types = selectedAssembly.GetTypes();

                    if(!string.IsNullOrEmpty(searchTextInternal))
                    {
                        types = System.Array.FindAll(types, (a) => GetTypeFullName(a).ToLower().Contains(searchTextInternal.ToLower()));
                    }


                    // System.Array.Sort<System.Type>(types, (a, b) => {return string.Compare(a.FullName, b.FullName); });

                    int beginItemIndex = pageIndex * maxPageItemNum;
                    int endItemIndex = Mathf.Min((pageIndex + 1) * maxPageItemNum, types.Length);

                    GUILayout.BeginHorizontal();
                    Title(string.Format("types({0}):", types.Length));
                    if(GUILayout.Button("[" + beginItemIndex + "-" + endItemIndex + "]", GUILayout.ExpandWidth(false)))
                    {
                        int pageNum = (types.Length / maxPageItemNum);
                        if(types.Length % maxPageItemNum != 0)
                        {
                            pageNum++;
                        }

                        pageIndex++;
                        pageIndex %= pageNum;
                    }
                    GUILayout.EndHorizontal();

                    
                    
                    for(int i = pageIndex * maxPageItemNum; i < (pageIndex + 1) * maxPageItemNum && i < types.Length; i++)
                    {
                        var t = types[i];
                        if(GUILayout.Button(GetTypeFullName(t)))
                        {
                            PushSelectedObj(t);
                            break;
                        }
                    }
                }
            }
            else
            {
                var b = GetSelectedObj(selectedObjs.Count - 1) as SelectedInfo;
                if(b != null)
                {
                    if(b.GetFieldType() != null)
                    {
                        ShowObjectInfo(b.fieldValue, b.GetFieldType(), b.fieldInfo as System.Reflection.MemberInfo);
                    }
                    else if(b.showType != null)
                    {
                        // if(b.fieldValue != null)
                        {
                            ShowObjectInfo(b.fieldValue, b.showType);
                        }
                        // else
                        // {
                        //     ShowObjectInfo(b.showType, b.showType.GetType());
                        // }
                    }
                    else
                    {
                        ShowObjectInfo(null, null);
                    }
                }
                // else
                // {
                //     var t = GetSelectedObj(selectedObjs.Count - 1).fieldValue;
                //     if(t is System.Type)
                //     {
                //         ShowObjectInfo(null, t as System.Type);
                //     }
                //     else
                //     {
                //         ShowObjectInfo(t, t.GetType());
                //     }
                // }
            }
        }


        GUILayout.EndVertical();
        GUILayout.EndScrollView();



        GUILayout.EndVertical();
    }


    void ShowObjectInfo(object obj, System.Type objType, System.Reflection.MemberInfo memberInfo = null)
    {
        if(memberInfo != null)
        {
            GUILayout.BeginHorizontal();
            Title("member info:");
            if(GUILayout.Button(memberInfo.ToString() + " | " + memberInfo.GetType()))
            {
                this.PushSelectedObj(memberInfo);
            }
            GUILayout.EndHorizontal();
        }


        GUILayout.Label("");
        if(objType == null)
        {
            GUILayout.Label("type: null");
            return;
        }

        // if(obj is System.Type)
        // {
        //     var tt = obj as System.Type;

        //     Title("type:");
        //     if(GUILayout.Button(GetTypeFullName(tt)))
        //     {
        //         SelectedInfo info = new SelectedInfo();
        //         info.showType = tt;
        //         this.PushSelectedObj(info);
        //         newSearchText = null;
        //     }

            
        //     GUILayout.Label("");
        //     Title("static members: ");
        //     ShowTypeFields(tt, null, false);
        //     GUILayout.Label("");
        //     Title("instance members: ");
        //     ShowTypeFields(tt, null, true);
        // }
        // else
        {
            // GUILayout.BeginHorizontal();
            // Title("show type data:");
            // if(GUILayout.Button(GetTypeFullName(objType)))
            // {
            //     SelectedInfo info = new SelectedInfo();
            //     info.showType = objType;
            //     this.PushSelectedObj(info);
            //     newSearchText = null;
            // }
            // GUILayout.EndHorizontal();


            // if(obj != null && objType != obj.GetType())
            // {
            //     GUILayout.BeginHorizontal();
            //     Title("convert to real type:");
            //     if(GUILayout.Button(GetTypeFullName(obj.GetType())))
            //     {
            //         this.PushSelectedObj(obj);
            //         newSearchText = null;
            //     }
            //     GUILayout.EndHorizontal();
            // }

            // if(obj != null && objType.BaseType != null)
            // {
            //     GUILayout.BeginHorizontal();
            //     Title("convert to base type:");
            //     if(GUILayout.Button(GetTypeFullName(objType.BaseType)))
            //     {
            //         SelectedInfo info = new SelectedInfo();
            //         info.fieldValue = obj;
            //         info.showType = objType.BaseType;
            //         this.PushSelectedObj(info);
            //         newSearchText = null;
            //     }
            //     GUILayout.EndHorizontal();
            // }

            System.Type tempObjType = objType;
            if(obj != null)
            {
                tempObjType = obj.GetType();
            }

            var tempObjType2 = tempObjType;
            {
                Title("types:");
                while(tempObjType2 != null)
                {
                    GUILayout.BeginHorizontal();
                    if(tempObjType2 == objType)
                    {
                        GUILayout.Label("current type:", GUILayout.ExpandWidth(false));
                        if(GUILayout.Button(GetTypeFullName(objType)))
                        {
                            SelectedInfo info = new SelectedInfo();
                            info.fieldValue = objType;
                            info.showType = objType.GetType();
                            this.PushSelectedObj(info);
                        }
                    }
                    else
                    {
                        if(obj != null)
                        {
                            GUILayout.Label("convert to:", GUILayout.ExpandWidth(false));
                        }
                        else
                        {
                            GUILayout.Label("base type:", GUILayout.ExpandWidth(false));
                        }

                        if(GUILayout.Button(GetTypeFullName(tempObjType2)))
                        {
                            if(obj != null)
                            {
                                SelectedInfo info = new SelectedInfo();
                                info.fieldValue = obj;
                                info.showType = tempObjType2;
                                this.PushSelectedObj(info);
                            }
                            else
                            {
                                PushSelectedObj(tempObjType2);
                            }
                        }
                    }

                    GUILayout.EndHorizontal();

                    tempObjType2 = tempObjType2.BaseType;
                }

                // if(typeof(System.Reflection.ICustomAttributeProvider).IsAssignableFrom(tempObjType))
                // {
                //     // var tempTypeObj = obj as System.Reflection.ICustomAttributeProvider;
                //     // var e = tempTypeObj.GetCustomAttributes(true);

                //     // if(e.Length > 0)
                //     // {
                //     //     GUILayout.Label("");
                //     //     Title(string.Format("CustomAttributes:"));
                //     //     foreach(var ee in e)
                //     //     {
                //     //         if(GUILayout.Button((ee.ToString())))
                //     //         {
                //     //             PushSelectedObj(ee);
                //     //             newSearchText = null;
                //     //         }
                //     //     }
                //     // }

                //     var tempTypeObj = tempObjType as System.Reflection.ICustomAttributeProvider;
                //     var e = tempTypeObj.GetCustomAttributes(true);

                //     // if(e.Length > 0)
                //     {
                //         GUILayout.Label("");
                //         Title(string.Format("CustomAttributes:"));
                //         foreach(var ee in e)
                //         {
                //             if(GUILayout.Button((ee.ToString())))
                //             {
                //                 PushSelectedObj(ee);
                //                 newSearchText = null;
                //             }
                //         }
                //     }
                // }

                if(obj != null && typeof(System.Reflection.ICustomAttributeProvider).IsAssignableFrom(tempObjType))
                {
                    var tempTypeObj = obj as System.Reflection.ICustomAttributeProvider;
                    var e = tempTypeObj.GetCustomAttributes(true);

                    if(e.Length > 0)
                    {
                        GUILayout.Label("");
                        Title(string.Format("CustomAttributes:"));
                        foreach(var ee in e)
                        {
                            if(GUILayout.Button((ee.ToString())))
                            {
                                PushSelectedObj(ee);
                            }
                        }
                    }

                    // var tempTypeObj = tempObjType as System.Reflection.ICustomAttributeProvider;
                    // var e = tempTypeObj.GetCustomAttributes(true);

                    // // if(e.Length > 0)
                    // {
                    //     GUILayout.Label("");
                    //     Title(string.Format("CustomAttributes:"));
                    //     foreach(var ee in e)
                    //     {
                    //         if(GUILayout.Button((ee.ToString())))
                    //         {
                    //             PushSelectedObj(ee);
                    //             newSearchText = null;
                    //         }
                    //     }
                    // }
                }
            }

            

            if(obj is System.Type)
            {
                var tempTypeObj = obj as System.Type;
                
                var interfaces = tempTypeObj.GetInterfaces();


                if(interfaces.Length > 0)
                {
                    GUILayout.Label("");
                    Title(string.Format("Interfaces:"));
                    foreach(var ee in interfaces)
                    {
                        if(GUILayout.Button(GetTypeFullName(ee)))
                        {
                            PushSelectedObj(ee);
                        }
                    }
                }

                {
                    var gta = tempTypeObj.GetNestedTypes();
                    if(gta.Length > 0)
                    {
                        GUILayout.Label("");
                        Title(string.Format("NestedTypes:"));
                        for(int i = 0; i < gta.Length; i++)
                        {
                            if(GUILayout.Button(GetTypeFullName(gta[i])))
                            {
                                PushSelectedObj(gta[i]);
                            }
                        }
                    }
                }
            }
            else if(obj is UnityEngine.SceneManagement.Scene)
            {
                var scene = (UnityEngine.SceneManagement.Scene)obj;
                var objs = scene.GetRootGameObjects();

                if(!string.IsNullOrEmpty(searchTextInternal))
                {
                    objs = System.Array.FindAll(objs, (a) => a.name.ToLower().Contains(searchTextInternal.ToLower()));
                }

                
                GUILayout.Label("");
                Title("GameObjects: ");
                System.Array.ForEach(objs, (a) =>
                {
                    if(GUILayout.Button(a.name))
                    {
                        PushSelectedObj(a);
                    }
                });
            }
            else if(obj is GameObject)
            {   
                var o = obj as GameObject;
                GUILayout.Label("");
                Title("components: ");
                var coms = o.GetComponents<UnityEngine.Component>();

                if(!string.IsNullOrEmpty(searchTextInternal))
                {
                    coms = System.Array.FindAll(coms, (a) => GetTypeFullName(a.GetType()).ToLower().Contains(searchTextInternal.ToLower()));
                }

                System.Array.ForEach(coms, (a) =>
                {
                    if(GUILayout.Button(GetTypeFullName(a.GetType())))
                    {
                        PushSelectedObj(a);
                    }
                });

                GUILayout.Label("");
                Title("child GameObjects: ");

                List<GameObject> childs = new List<GameObject>();
                for(int i = 0; i < o.transform.childCount; i++)
                {
                    var t = o.transform.GetChild(i);
                    childs.Add(t.gameObject);   
                }

                if(!string.IsNullOrEmpty(searchTextInternal))
                {
                    childs = childs.FindAll((a) => GetTypeFullName(a.GetType()).ToLower().Contains(searchTextInternal.ToLower()));
                }

                for(int i = 0; i < childs.Count; i++)
                {
                    var t = childs[i];

                    if(GUILayout.Button(t.name))
                    {
                        PushSelectedObj(t.gameObject);
                    }
                }
            }
            else if(obj is Material)
            {
                var mat = obj as Material;
                var keywords = mat.shaderKeywords;
                if(keywords.Length > 0)
                {
                    GUILayout.Label("");
                    Title("keywords: ");
                    foreach(var kw in keywords)
                    {
                        GUILayout.Label(kw + ": " + mat.IsKeywordEnabled(kw));
                    }
                }

                var proNames = mat.GetTexturePropertyNames();
                if(proNames.Length > 0)
                {
                    GUILayout.Label("");
                    Title("textures: ");
                    foreach(var pn in proNames)
                    {
                        var tex = mat.GetTexture(pn);
                        if(tex != null)
                        {
                            if(GUILayout.Button(pn + ": " + tex))
                            {
                                PushSelectedObj(tex);
                            }
                        }
                        else
                        {
                            GUILayout.Label(pn);
                        }
                    }
                }
            }
            else if(obj is Texture2D)
            {
                var tex = obj as Texture2D;
                GUILayout.Label("");
                Title("preview:");
                
                int width = 300;
                var ss = GUI.skin.box.normal.background;
                GUI.skin.box.normal.background = tex;
                GUILayout.Box("", GUILayout.Width(width), GUILayout.Height(width / ((float)tex.width / tex.height)));
                GUI.skin.box.normal.background = ss;

            }
            else if(obj is AssetBundle)
            {
                var ab = obj as AssetBundle;

                GUILayout.Label("");
                if(GUILayout.Button("show asset paths"))
                {
                    if(ab.isStreamedSceneAssetBundle)
                    {
                        PushSelectedObj(ab.GetAllScenePaths());
                    }
                    else
                    {
                        PushSelectedObj(ab.GetAllAssetNames());
                    }
                }
            }
            else if(obj is System.Reflection.MethodBase)
            {
                var m = obj as System.Reflection.MethodBase;

                if(m.GetMethodBody() != null)
                {
                    GUILayout.Label("");
                    if(GUILayout.Button("method body"))
                    {
                        this.PushSelectedObj(m.GetMethodBody());
                    }
                }
            }
            


            // if(baseTypeSet.Contains(objType))
            // {
            //     GUILayout.Label(obj.ToString());
            // }
            // else
            {
                if(obj != null)
                {
                    // if(objType.IsGenericType && objType.GetGenericTypeDefinition() == typeof(List<>))
                    if(typeof(ICollection).IsAssignableFrom(objType) && typeof(IEnumerable).IsAssignableFrom(objType) && !typeof(IDictionary).IsAssignableFrom(objType))
                    {
                        GUILayout.Label("");
                        Title(string.Format("elements({0}):", (obj as ICollection).Count));
                        int index = 0;
                        foreach(var item in obj as IEnumerable)
                        {
                            ShowIndexValue(index, item);
                            index++;
                        }
                    }
                    else
                    {
                        bool implementICollection = objType.GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(ICollection<>));

                        if(implementICollection)
                        {
                            GUILayout.Label("");
                            Title(string.Format("elements:"));
                            foreach(var item in obj as IEnumerable)
                            {
                                ShowIndexValue(-1, item);
                            }
                        }
                    }
                    
                    if(objType.IsSubclassOf(typeof(System.MulticastDelegate)))
                    {
                        var tempDelegate = obj as System.MulticastDelegate;
                        var tempDelegates = tempDelegate.GetInvocationList();

                        GUILayout.Label("");
                        Title(string.Format("InvocationList{0}:", tempDelegates.Length));
                        for(int i = 0; i < tempDelegates.Length; i++)
                        {
                            ShowIndexValue(i, tempDelegates[i]);
                        }
                    }
                }


                GUILayout.Label("");
                Title("instance members: ");
                ShowTypeFields(objType, obj, true);
                GUILayout.Label("");
                Title("static members: ");
                ShowTypeFields(objType, null, false);


                GUILayout.Label("----------------------------------------");
                GUILayout.Label("");
                if(GUILayout.Button("show methods: " + showMethods))
                {
                    showMethods = !showMethods;
                }

                if(showMethods)
                {
                    GUILayout.Label("");
                    Title("instance methods: ");
                    ShowTypeMethods(objType, obj, true);
                    GUILayout.Label("");
                    Title("static methods: ");
                    ShowTypeMethods(objType, null, false);
                }
            }
        }
    }

    void Title(string title)
    {
        var oldStyle = GUI.skin.label.fontStyle;
        var oldColor = GUI.contentColor;

        GUI.skin.label.fontStyle = FontStyle.Bold;
        GUI.contentColor = Color.yellow;
        GUILayout.Label(title, GUILayout.ExpandWidth(false));

        GUI.contentColor = oldColor;
        GUI.skin.label.fontStyle = oldStyle;
    }

    string GetTypeFullName(System.Type t)
    {
        string typeName = t.FullName;
        if(typeName == null)
        {
            typeName = t.Name;
            if(typeName != null)
            {
                typeName = t.Namespace + "." + t.Name;
            }
        }

        if(t.IsGenericType)
        {
            // if(typeName != null)
            // {
            //     int index = typeName.IndexOf("`");

            //     typeName = index > 0? typeName.Substring(0, index) + "<": typeName;
            //     var gta = t.GenericTypeArguments;
            //     for(int i = 0; i < gta.Length; i++)
            //     {
            //         typeName += GetTypeFullName(gta[i]);
            //         if(i < gta.Length - 1)
            //         {
            //             typeName += ",";
            //         }
            //     }

            //     typeName += ">";
            //     return typeName;
            // }
            // else
            // {
            //     return "?";
            // }

            return t.ToString();

        }
        else
        {
            return typeName;
        }
    }

    void PushSelectedObj(object obj)
    {
        if(!(obj is SelectedInfo))
        {
            SelectedInfo sInfo = new SelectedInfo();
            if(obj is System.Type)
            {
                sInfo.showType = obj as System.Type;
                obj = sInfo;
            }
            else
            {
                sInfo.fieldValue = obj;
                sInfo.showType = obj.GetType();
                obj = sInfo;
            }
        }


        var selectedObj = obj as SelectedInfo;
        selectedObj.searchText = searchText;

        this.selectedObjs.Add(obj);
        searchText = null;
        pageIndex = 0;
    }

    SelectedInfo GetSelectedObj(int index)
    {
        return this.selectedObjs[index] as SelectedInfo;
    }

    void ShowIndexValue(int index, object value)
    {
        string indexStr = "";
        if(index >= 0)
        {
            indexStr = string.Format("[{0}]: ", index);
        }

        if(value == null)
        {
            GUILayout.Label(indexStr + "null");
            return;
        }

        var fieldType = value.GetType();
        string fieldTypeName = GetTypeFullName(fieldType);

        // if(baseTypeSet.Contains(fieldType))
        // {
        //     // if(fieldType.IsEnum)
        //     // {
        //     //     if(GUILayout.Button(indexStr + value + " | " + fieldTypeName))
        //     //     {
        //     //         this.PushSelectedObj(fieldType);
        //     //         newSearchText = null;
        //     //     }
        //     // }
        //     // else
        //     {
        //         GUILayout.Label(indexStr + value + " | " + fieldTypeName);
        //     }
        // }
        // else
        {
            string text = null;
            // System.Func<object, string> toStringFunc = null;
            // if(showSimpleValueTypeSet.TryGetValue(fieldType, out toStringFunc))
            // {
            //     text = indexStr + toStringFunc(value) + " | " + fieldTypeName;
            // }
            // else
            {
                foreach(var t in showValueTypeSet)
                {
                    if(fieldType.IsGenericType && t.Key.IsGenericTypeDefinition)
                    {
                        if(fieldType.GetGenericTypeDefinition() == t.Key)
                        {
                            text = t.Value(value);
                            break;
                        }
                    }
                    else
                    {
                        if(!t.Key.IsGenericTypeDefinition)
                        {
                            if(fieldType.IsSubclassOf(t.Key) || t.Key.IsAssignableFrom(fieldType))
                            {
                                text = t.Value(value);
                                break;
                            }
                        }
                    }
                }
            }

            if(text == null)
            {
                text = indexStr + (value??"null") + " | " + fieldTypeName;
            }

            if(string.IsNullOrEmpty(text))
            {
                text = indexStr + fieldTypeName;
            }

            if(GUILayout.Button(text))
            {
                if(value != null)
                {
                    this.PushSelectedObj(value);
                }
            }
        }
    }

    object GetFieldValue(object a, object obj, out bool throwException)
    {
        try
        {
            throwException = false;
            if(a is System.Reflection.FieldInfo)
            {
                return (a as System.Reflection.FieldInfo).GetValue(obj);
            }
            else if(a is System.Reflection.PropertyInfo)
            {
                var p = a as System.Reflection.PropertyInfo;
                return p.GetValue(obj);
            }
            
            return null;
        }
        catch(System.Exception e)
        {
            throwException = true;
            return e;
        }
    }

    void ShowOneField(object fieldInfo, object obj)
    {
        bool isStatic = false;
        System.Type fieldType = null;
        string flag = GetFlag(fieldInfo);
        string fieldName = (fieldInfo as System.Reflection.MemberInfo).Name;

        if(fieldInfo is System.Reflection.FieldInfo)
        {
            var a = fieldInfo as System.Reflection.FieldInfo;
            isStatic = a.IsStatic;
            fieldType = a.FieldType;
        }
        else if(fieldInfo is System.Reflection.PropertyInfo)
        {
            var a = fieldInfo as System.Reflection.PropertyInfo;
            isStatic = a.GetGetMethod()?.IsStatic == true || a.GetSetMethod()?.IsStatic == true;
            fieldType = a.PropertyType;
        }
        else if(fieldInfo is System.Reflection.MethodBase)
        {
            var a = fieldInfo as System.Reflection.MethodBase;
            isStatic = a.IsStatic;



            
            // string genericParamStr = null;
            // if(a.IsGenericMethod)
            // {
            //     var b = a.GetGenericArguments();
            //     for(int i = 0; i < b.Length; i++)
            //     {
            //         b[i].FullName
            //     }
            // }

            // string str = a.ReturnType + " " + a.Name + "(";
            // var methodsParams = a.GetParameters();
            // for(int i = 0; i < methodsParams.Length; i++)
            // {
            //     str += methodsParams[i].ParameterType + " " + methodsParams[i].Name;

            //     if(i < methodsParams.Length - 1)
            //     {
            //         str += ",";
            //     }
            // }

            // str += ")";


            string str = a.ToString();
            if(GUILayout.Button(str))
            {
                this.PushSelectedObj(a);
            }
            return;
        }





        bool throwException = false;
        object objValue = null;

        if(isStatic || obj != null)
        {
            objValue = GetFieldValue(fieldInfo, obj, out throwException);
        }
        
        string fieldTypeName = GetTypeFullName(fieldType);



        if(objValue is System.Exception && throwException)
        {
            var e = objValue;
            var oldColor = GUI.contentColor;
            GUI.contentColor = Color.red;
            if(GUILayout.Button(flag + GetTypeFullName(e.GetType()) + " | " + fieldName + ": " + fieldTypeName))
            {
                this.PushSelectedObj(e);
            }
            GUI.contentColor = oldColor;
        }
        else
        {
            // if(baseTypeSet.Contains(fieldType))
            // {
            //     GUILayout.Label(flag + fieldName + ": " + (objValue??"null") + " | " + fieldTypeName); 
            // }
            // else
            {
                string text = null;
                
                if(objValue != null)
                {
                    // System.Func<object, string> toStringFunc = null;
                    // if(showSimpleValueTypeSet.TryGetValue(fieldType, out toStringFunc))
                    // {
                    //     text = flag + fieldName + ": " + toStringFunc(objValue) + " | " + fieldTypeName;
                    // }
                    // else
                    {
                        foreach(var t in showValueTypeSet)
                        {
                            if(fieldType.IsGenericType && t.Key.IsGenericTypeDefinition)
                            {
                                if(fieldType.GetGenericTypeDefinition() == t.Key)
                                {
                                    text = flag + fieldName + ": " + t.Value(objValue) + " | " + fieldTypeName;
                                    break;
                                }
                            }
                            else
                            {
                                if(!t.Key.IsGenericTypeDefinition)
                                {
                                    if(fieldType.IsSubclassOf(t.Key) || t.Key.IsAssignableFrom(fieldType))
                                    {
                                        text = flag + fieldName + ": " + t.Value(objValue) + " | " + fieldTypeName;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }

                if(text == null)
                {
                    text = flag + fieldName + ": " + (objValue??"null") + " | " + fieldTypeName;  
                }

                if(string.IsNullOrEmpty(text))
                {
                    text = flag + fieldName + ": " + fieldTypeName;
                }
                
                if(GUILayout.Button(text))
                {
                    if(isStatic || obj != null)
                    {
                        SelectedInfo info = new SelectedInfo();
                        info.fieldValue = objValue;
                        info.fieldInfo = fieldInfo;
                        info.obj = obj;
                        this.PushSelectedObj(info);
                    }
                    else
                    {
                        this.PushSelectedObj(fieldType);
                    }

                }
            }
        }
    }

    void ShowTypeFields(System.Type objType, object obj, bool forceShowInstance)
    {
        System.Reflection.FieldInfo[] fields = objType.GetFields(((obj == null && !forceShowInstance)? System.Reflection.BindingFlags.Static: System.Reflection.BindingFlags.Instance) | System.Reflection.BindingFlags.Public | (publicMemberOnly? System.Reflection.BindingFlags.Default: System.Reflection.BindingFlags.NonPublic));

        if(!string.IsNullOrEmpty(searchTextInternal))
        {
            fields = System.Array.FindAll(fields, (a) => a.Name.ToLower().Contains(searchTextInternal.ToLower()));
        }



        foreach(var a in fields)
        {
            bool notSupport = false;
            var customAttrs = a.GetCustomAttributes(typeof(System.ObsoleteAttribute), true);
            foreach(var c in customAttrs)
            {
                var d = c as System.ObsoleteAttribute;
                if(d.IsError)
                {
                    notSupport = true;
                    break;
                }
            }

            if(notSupport)
            {
                continue;
            }

            ShowOneField(a, obj);


        }

        System.Reflection.PropertyInfo[] propertyInfos = objType.GetProperties(((obj == null && !forceShowInstance)? System.Reflection.BindingFlags.Static: System.Reflection.BindingFlags.Instance) | System.Reflection.BindingFlags.Public | (publicMemberOnly? System.Reflection.BindingFlags.Default: System.Reflection.BindingFlags.NonPublic));


        if(!string.IsNullOrEmpty(searchTextInternal))
        {   
            propertyInfos = System.Array.FindAll(propertyInfos, (a) => a.Name.ToLower().Contains(searchTextInternal.ToLower()));
        }

        foreach(var a in propertyInfos)
        {
            if(obj is UnityEngine.Renderer && a.Name == "material" || a.Name == "materials")
            {
                continue;
            }

            bool notSupport = false;
            var customAttrs = a.GetCustomAttributes(typeof(System.ObsoleteAttribute), true);
            foreach(var c in customAttrs)
            {
                var d = c as System.ObsoleteAttribute;
                if(d.IsError)
                {
                    notSupport = true;
                    break;
                }
            }

            if(notSupport)
            {
                continue;
            }

            if(obj is System.Type)
            {
                var t = obj as System.Type;

                if(a.Name == "DeclaringMethod" && a.PropertyType == typeof(System.Reflection.MethodBase) && !t.IsGenericParameter)
                {
                     var oldColor = GUI.contentColor;
                    GUI.contentColor = Color.gray;
                    GUILayout.Label("ignore " + a.Name + " " + a.PropertyType);
                    GUI.contentColor = oldColor;

                    continue;
                }
            }


    
            try
            {
                ShowOneField(a, obj);
            }
            catch(System.Exception e)
            {
                Debug.LogException(e);
            }
            
        };
    }

    
    void ShowTypeMethods(System.Type objType, object obj, bool forceShowInstance)
    {
        var constructorInfos = objType.GetConstructors(((obj == null && !forceShowInstance)? System.Reflection.BindingFlags.Static: System.Reflection.BindingFlags.Instance) | System.Reflection.BindingFlags.Public | (publicMemberOnly? System.Reflection.BindingFlags.Default: System.Reflection.BindingFlags.NonPublic));

        if(!string.IsNullOrEmpty(searchTextInternal))
        {
            constructorInfos = System.Array.FindAll(constructorInfos, (a) => a.Name.ToLower().Contains(searchTextInternal.ToLower()));
        }



        foreach(var a in constructorInfos)
        {
            bool notSupport = false;
            var customAttrs = a.GetCustomAttributes(typeof(System.ObsoleteAttribute), true);
            foreach(var c in customAttrs)
            {
                var d = c as System.ObsoleteAttribute;
                if(d.IsError)
                {
                    notSupport = true;
                    break;
                }
            }

            if(notSupport)
            {
                continue;
            }

            ShowOneField(a, obj);
        }

        

        var methods = objType.GetMethods(((obj == null && !forceShowInstance)? System.Reflection.BindingFlags.Static: System.Reflection.BindingFlags.Instance) | System.Reflection.BindingFlags.Public | (publicMemberOnly? System.Reflection.BindingFlags.Default: System.Reflection.BindingFlags.NonPublic));

        if(!string.IsNullOrEmpty(searchTextInternal))
        {
            methods = System.Array.FindAll(methods, (a) => a.Name.ToLower().Contains(searchTextInternal.ToLower()));
        }



        foreach(var a in methods)
        {
            bool notSupport = false;
            var customAttrs = a.GetCustomAttributes(typeof(System.ObsoleteAttribute), true);
            foreach(var c in customAttrs)
            {
                var d = c as System.ObsoleteAttribute;
                if(d.IsError)
                {
                    notSupport = true;
                    break;
                }
            }

            if(notSupport)
            {
                continue;
            }

            ShowOneField(a, obj);
        }

        // System.Reflection.PropertyInfo[] propertyInfos = objType.GetProperties(((obj == null && !forceShowInstance)? System.Reflection.BindingFlags.Static: System.Reflection.BindingFlags.Instance) | System.Reflection.BindingFlags.Public | (publicMemberOnly? System.Reflection.BindingFlags.Default: System.Reflection.BindingFlags.NonPublic));


        // if(!string.IsNullOrEmpty(searchText))
        // {   
        //     propertyInfos = System.Array.FindAll(propertyInfos, (a) => a.Name.ToLower().Contains(searchText.ToLower()));
        // }

        // foreach(var a in propertyInfos)
        // {
        //     bool notSupport = false;
        //     var customAttrs = a.GetCustomAttributes(typeof(System.ObsoleteAttribute), true);
        //     foreach(var c in customAttrs)
        //     {
        //         var d = c as System.ObsoleteAttribute;
        //         if(d.IsError)
        //         {
        //             notSupport = true;
        //             break;
        //         }
        //     }

        //     if(notSupport)
        //     {
        //         continue;
        //     }

        //     if(obj is System.Type)
        //     {
        //         var t = obj as System.Type;

        //         if(a.Name == "DeclaringMethod" && a.PropertyType == typeof(System.Reflection.MethodBase) && !t.IsGenericParameter)
        //         {
        //              var oldColor = GUI.contentColor;
        //             GUI.contentColor = Color.gray;
        //             GUILayout.Label("ignore " + a.Name + " " + a.PropertyType);
        //             GUI.contentColor = oldColor;

        //             continue;
        //         }
        //     }


    
        //     try
        //     {
        //         ShowOneField(a, obj);
        //     }
        //     catch(System.Exception e)
        //     {
        //         Debug.LogException(e);
        //     }
            
        // };
    }

    string GetFlag(object fieldInfo)
    {
        string result = "";

        var a = fieldInfo as System.Reflection.FieldInfo;
        if(a != null)
        {
            // if(a.IsStatic)
            // {
            //     result += "s";
            // }

            if(a.IsPublic)
            {
                // result += "p";
            }
            else
            {
                result += "*";
            }
        }
        else
        {
            var b = fieldInfo as System.Reflection.PropertyInfo;
            if(b != null)
            {
                // if(b.GetGetMethod()?.IsStatic == true || b.GetSetMethod()?.IsStatic == true)
                // {
                //     result += "s";
                // }

                if(b.GetGetMethod()?.IsPublic == true || b.GetSetMethod()?.IsPublic == true)
                {
                    // result += "p";
                }
                else
                {
                    result += "*";
                }
            }
        }

        return result;
    }

}

}